@file:Suppress("UNCHECKED_CAST")

package org.liaohailong.library.util

import com.google.gson.Gson
import com.google.gson.JsonArray
import com.google.gson.JsonObject
import com.google.gson.JsonParser

/**
 * Author: liaohailong
 * Date: 2019/4/27
 * Time: 10:52
 * Description: Json处理工具
 **/
object JsonUtil {

    private val gson: Gson = Gson()
    private val jsonParser: JsonParser = JsonParser()

    fun stringToJsonObject(jsonString: String): JsonObject {
        return jsonParser.parse(jsonString).asJsonObject
    }

    fun stringToJsonArray(jsonString: String): JsonArray {
        return jsonParser.parse(jsonString).asJsonArray
    }

    fun <T> stringToObject(jsonString: String, clz: Class<T>): T {
        return gson.fromJson<T>(jsonString, clz)
    }

    fun <T> stringToList(string: String, clz: Class<T>): List<T> {
        val jsonArray = stringToJsonArray(string)
        val result: MutableList<T> = mutableListOf()
        for (jsonElement in jsonArray) {
            when {
                String::class.java.isAssignableFrom(clz) -> {
                    result.add(jsonElement.asString as T)
                }
                Int::class.java.isAssignableFrom(clz) -> {
                    result.add(jsonElement.asInt as T)
                }
                Long::class.java.isAssignableFrom(clz) -> {
                    result.add(jsonElement.asLong as T)
                }
                Float::class.java.isAssignableFrom(clz) -> {
                    result.add(jsonElement.asFloat as T)
                }
                Double::class.java.isAssignableFrom(clz) -> {
                    result.add(jsonElement.asDouble as T)
                }
                Boolean::class.java.isAssignableFrom(clz) -> {
                    result.add(jsonElement.asBoolean as T)
                }
                else -> {
                    val jsonObject = jsonElement.asJsonObject
                    val obj = jsonToObject(jsonObject, clz)
                    result.add(obj)
                }
            }
        }
        return result
    }


    fun <T> jsonToObject(jsonObject: JsonObject, clz: Class<T>): T {
        return gson.fromJson(jsonObject, clz)
    }
}